#pragma once

#include <windows.h>
#include <tchar.h>
#include <string>
#include <list>
#include <iostream>

#include "Serializable.h"

namespace platform {

class XStringList;


// NOTE(todo): resolve TCHAR type during compilation, in
// order to make all conversions tchar-type dependant

class XString : public std::basic_string<TCHAR>, public ISerializable
{
public:
	XString(void) {}
	XString(const TCHAR *s) : std::basic_string<TCHAR>(s == NULL ? _T("") : s) {}
	XString(const TCHAR *s, size_t len) : std::basic_string<TCHAR>(s, len) {}
	XString(const std::string &s);

	LPCTSTR getTStr(void) const { return c_str(); }

	std::string getANSIString(void) const;

	inline void toUpper(void);

	XString & operator=(const TCHAR *s) { std::basic_string<TCHAR>::operator=(s); return (*this);}

	void split(TCHAR sep, XStringList &tokens) const;


	// implementing ISerializable
public:
	virtual void saveToStream(std::ostream &os) const;
	virtual void readFromStream(std::istream &is);
	virtual void writeDebugInfo(std::ostream &os) const;

public:
	virtual ~XString(void) {}
};


class XStringList : public std::list<XString>
{
	typedef std::list<XString> list_t;

public:
	inline void join(TCHAR sep, XString &res) const {
		res.clear();
		bool bFirst = true;
		for (list_t::const_iterator it = begin(); it != end(); ++it) {
			if (!bFirst) res += sep;
			bFirst = false;
			res += *it;
		}
	}
};



inline void XString::toUpper(void) {
	for (std::basic_string<TCHAR>::iterator it = begin(); it != end(); ++it)
		if (_istlower(*it))
			*it = _totupper(*it);
}

} // end namespace
